﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Text;

namespace LogManager.Helpers
{
    public class DatePager : IHtmlString
    {
        private readonly ViewContext _viewContext;

        private string _paginationFormat = "Showing {0} - {1}";
        private string _paginationPrev = "prev";
        private string _paginationNext = "next";
        private string _pageQueryName = "datePage";
        private int _datePage = 1;
        private Func<int, string> _urlBuilder;

        private string _serverName;
        private string _logName;

        /// <summary>
        /// Creates a new instance of the Pager class.
        /// </summary>
        /// <param name="pagination">The IPagination datasource</param>
        /// <param name="context">The view context</param>
        public DatePager(ViewContext context,string serverName = null, string logName = null)
        {
            _serverName = serverName;
            _logName = logName;

            _viewContext = context;

            string datePage = _viewContext.RequestContext.HttpContext.Request.QueryString.Get(_pageQueryName);
            if (datePage != null)
                _datePage = int.Parse(datePage);

            _urlBuilder = CreateDefaultUrl;

            
        }

        protected ViewContext ViewContext
        {
            get { return _viewContext; }
        }

        /// <summary>
        /// Specifies the format to use when rendering a pagination containing multiple pages. 
        /// The default is 'Showing {0} - {1} of {2}' (eg 'Showing 1 to 3 of 6')
        /// </summary>
        public DatePager Format(string format)
        {
            _paginationFormat = format;
            return this;
        }

        /// <summary>
        /// Text for the 'prev' link
        /// </summary>
        public DatePager Previous(string previous)
        {
            _paginationPrev = previous;
            return this;
        }

        /// <summary>
        /// Text for the 'next' link
        /// </summary>
        public DatePager Next(string next)
        {
            _paginationNext = next;
            return this;
        }

        /// <summary>
        /// Uses a lambda expression to generate the URL for the page links.
        /// </summary>
        /// <param name="urlBuilder">Lambda expression for generating the URL used in the page links</param>
        public DatePager Link(Func<int, string> urlBuilder)
        {
            _urlBuilder = urlBuilder;
            return this;
        }

        // For backwards compatibility with WebFormViewEngine
        public override string ToString()
        {
            return ToHtmlString();
        }

        public string ToHtmlString()
        {
            var builder = new StringBuilder();

            builder.Append("<div class='pagination'>");
            RenderLeftSideOfPager(builder);
            builder.Append(" ");
            RenderRightSideOfPager(builder);
            builder.Append(@"</div>");

            return builder.ToString();
        }

        protected virtual void RenderLeftSideOfPager(StringBuilder builder)
        {
            builder.Append("<span class='pagination'>");
            RenderNumberOfItemsWhenThereAreMultipleItemsPerPage(builder);
            builder.Append("</span>");
        }

        protected virtual void RenderRightSideOfPager(StringBuilder builder)
        {
            builder.Append("<span class='pagination'>");
            builder.Append(CreatePageLink(_datePage+1, _paginationPrev));
            builder.Append(" | ");

            //Only render a link to the next page if there is another page after the current page.
            if (_datePage > 1)
                builder.Append(CreatePageLink(_datePage-1, _paginationNext));
            else
                builder.Append(_paginationNext);
            builder.Append("</span>");
        }

        protected virtual void RenderNumberOfItemsWhenThereAreMultipleItemsPerPage(StringBuilder builder)
        {
            builder.AppendFormat(_paginationFormat, FromDate(_datePage).ToShortDateString(), ToDate(_datePage).ToShortDateString());
        }

        public static DateTime ToDate(int datePage)
        {
            return DateTime.Now.AddDays((datePage - 1) * -30);
        }

        public static DateTime FromDate(int datePage)
        {
            return DateTime.Now.AddDays(datePage * -30);
        }

        private string CreatePageLink(int pageNumber, string text)
        {
            var builder = new TagBuilder("a");
            builder.SetInnerText(text);
            builder.MergeAttribute("href", _urlBuilder(pageNumber));
            return builder.ToString(TagRenderMode.Normal);
        }

        private string CreateDefaultUrl(int pageNumber)
        {
            var routeValues = new RouteValueDictionary();

            foreach (var key in _viewContext.RequestContext.HttpContext.Request.QueryString.AllKeys.Where(key => key != null))
            {
                routeValues[key] = _viewContext.RequestContext.HttpContext.Request.QueryString[key];
            }

            routeValues[_pageQueryName] = pageNumber;

            var url = UrlHelper.GenerateUrl(null, null, null, routeValues, RouteTable.Routes, _viewContext.RequestContext, true);
            return url;
        }
    }
}